#include "can.h"
CanTxMsg Tx_Message;
CanRxMsg Rx0_Message;
CanRxMsg Rx1_Message;
void (*rx0_callback)();
void (*rx1_callback)();
//CAN can(CAN1,&PB8,&PB9);
typedef  struct {
	unsigned char   SJW;
	unsigned char   BS1;
	unsigned char   BS2;
	unsigned short  PreScale;
} tCAN_BaudRate;
tCAN_BaudRate  CAN_BaudRateInitTab[]= {      // CLK=36MHz
	{CAN_SJW_1tq,CAN_BS1_10tq,CAN_BS2_1tq,3},     // 1M
	{CAN_SJW_1tq,CAN_BS1_8tq,CAN_BS2_1tq,4},     // 900K
	{CAN_SJW_2tq,CAN_BS1_13tq,CAN_BS2_1tq,13},     // 800K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,3},     // 666K
	{CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_1tq,4},     // 600K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,4},     // 500K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,5},     // 400K
	{CAN_SJW_1tq,CAN_BS1_15tq,CAN_BS2_1tq,7},    // 300K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,8},    // 250K
	{CAN_SJW_1tq,CAN_BS1_14tq,CAN_BS2_1tq,10},	// 225K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,10},    // 200K
	{CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_1tq,15},	// 160K
	{CAN_SJW_1tq,CAN_BS1_14tq,CAN_BS2_1tq,15},    // 150K
	{CAN_SJW_1tq,CAN_BS1_8tq,CAN_BS2_1tq,25},	// 144K
	{CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_1tq,36},   // 125K
	{CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_1tq,20},	// 120K
	{CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_1tq,45},    // 100K
	{CAN_SJW_1tq,CAN_BS1_14tq,CAN_BS2_1tq,25},   // 90K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,25},   // 80K
	{CAN_SJW_1tq,CAN_BS1_14tq,CAN_BS2_1tq,30},	// 75K
	{CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_1tq,40},    // 60K
	{CAN_SJW_1tq,CAN_BS1_14tq,CAN_BS2_1tq,45},    // 50K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,50},    // 40K
	{CAN_SJW_1tq,CAN_BS1_14tq,CAN_BS2_1tq,75},   // 30K
	{CAN_SJW_1tq,CAN_BS1_16tq,CAN_BS2_1tq,100},   // 20K
};
CAN::CAN(CAN_TypeDef* CANx,GPIO* p_pin_rx, GPIO* p_pin_tx)
{
	this->_CANx = CANx;
	this->pin_tx = p_pin_tx;
	this->pin_rx = p_pin_rx;
}

void CAN::begin(BSP_CAN_BAUD bps)
{
	
	pin_rx->mode(INPUT_PU);
	pin_tx->mode(AF_PP);
	this->tx_message = &Tx_Message;
	this->rx0_message = &Rx0_Message;
	this->rx1_message = &Rx1_Message;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);//使用PB8是使用此语句
	/*CAN寄存器初始化*/
	CAN_DeInit(_CANx);
	set_filter(CAN_FilterMode_IdMask,CAN_FilterScale_32bit,0,0x00000000,0x00000000);
	set_bps(bps);
}
void CAN::nvic_init()
{
//	NVIC_InitTypeDef NVIC_InitStructure;
}
void CAN::set_filter(u8 Fifo,u8 nCanType,u8 num,u32 ID,u32 Mask)
{
	CAN_FilterInitTypeDef  CAN_FilterInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	/*中断设置*/
	if(0 == num)
	{
		NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;	   //CAN1 RX0中断
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_RX0_PreemptionPriority;		   //抢占优先级0
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN1_RX0_SubPriority;			   //子优先级为0
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
	}
	else if (1 == num)
	{
		NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;	   //CAN1 RX0中断
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_RX1_PreemptionPriority;		   //抢占优先级0
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN1_RX1_SubPriority;			   //子优先级为0
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);
	}
	/*CAN过滤器初始化*/
	CAN_FilterInitStructure.CAN_FilterNumber=num;						//过滤器组0
	CAN_FilterInitStructure.CAN_FilterMode=Fifo;	//工作在标识符屏蔽位模式
	CAN_FilterInitStructure.CAN_FilterScale=nCanType;	//过滤器位宽
	/* 使能报文标示符过滤器按照标示符的内容进行比对过滤，扩展ID不是如下的就抛弃掉，是的话，会存入FIFO0。 */

	CAN_FilterInitStructure.CAN_FilterIdHigh= ((ID<<3)&0xFFFF0000)>>16;				//要过滤的ID高位 
	CAN_FilterInitStructure.CAN_FilterIdLow= ((ID<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //要过滤的ID低位 
	Mask <<= 3;
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh= (u16)(Mask >> 16);			//过滤器高16位每位必须匹配
	CAN_FilterInitStructure.CAN_FilterMaskIdLow= (u16)(Mask & 0x0000ffff);			//过滤器低16位每位必须匹配
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ;				//过滤器被关联到FIFO0
	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;			//使能过滤器
	CAN_FilterInit(&CAN_FilterInitStructure);
	CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}
void CAN::set_bps(BSP_CAN_BAUD BaudRate)
{
	CAN_InitTypeDef        CAN_InitStructure;
	_bps = BaudRate;
	/************************CAN通信参数设置**********************************/
	
	CAN_StructInit(&CAN_InitStructure);
	/*CAN单元初始化*/
	CAN_InitStructure.CAN_TTCM=DISABLE;			   //MCR-TTCM  关闭时间触发通信模式使能
	CAN_InitStructure.CAN_ABOM=ENABLE;			   //MCR-ABOM  自动离线管理 
	CAN_InitStructure.CAN_AWUM=ENABLE;			   //MCR-AWUM  使用自动唤醒模式
	CAN_InitStructure.CAN_NART=DISABLE;			   //MCR-NART  禁止报文自动重传	  DISABLE-自动重传
	CAN_InitStructure.CAN_RFLM=DISABLE;			   //MCR-RFLM  接收FIFO 锁定模式  DISABLE-溢出时新报文会覆盖原有报文  
	CAN_InitStructure.CAN_TXFP=DISABLE;			   //MCR-TXFP  发送FIFO优先级 DISABLE-优先级取决于报文标示符 
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;  //正常工作模式
	CAN_InitStructure.CAN_SJW = CAN_BaudRateInitTab[BaudRate].SJW;//配置波特率为1M
	CAN_InitStructure.CAN_BS1 = CAN_BaudRateInitTab[BaudRate].BS1;
	CAN_InitStructure.CAN_BS2 = CAN_BaudRateInitTab[BaudRate].BS2;
	CAN_InitStructure.CAN_Prescaler = CAN_BaudRateInitTab[BaudRate].PreScale;
	CAN_Init(_CANx, &CAN_InitStructure);
}
//uint8_t CAN::read(CanRxMsg *pCanMsg, u16 WaitTime)
//{
//	return 0;
//}
uint8_t CAN::write(uint32_t id,uint8_t *data,u8 len)
{
	u8 i;
	//TxMessage.StdId=0x00;						 
	tx_message->ExtId=id;					 
	tx_message->IDE=CAN_ID_EXT;					
	tx_message->RTR=CAN_RTR_DATA;				 
	tx_message->DLC=len;							
	for(i=0;i<len;i++)
	{
		tx_message->Data[i]=data[i];	
	}
	CAN_Transmit(_CANx,tx_message);
	return 0;
}
void CAN::interrupt(FunctionalState enable)
{

}
void CAN::attach_interrupt_rx0(void (*callback_fun)(void))
{
	rx0_callback = callback_fun;
}
void CAN::attach_interrupt_rx1(void (*callback_fun)(void))
{
	rx1_callback = callback_fun;
}
#ifdef __cplusplus
extern "C" {
#endif
	void  USB_LP_CAN1_RX0_IRQHandler(void);
	void CAN1_RX1_IRQHandler();
#ifdef __cplusplus
}
#endif
void  USB_LP_CAN1_RX0_IRQHandler(void)//CAN_FIFO_0接收中断
{
	//	u8 can_data[8] = {0};
	/*从邮箱中读出报文*/
	CAN_Receive(CAN1, CAN_FIFO0, &Rx0_Message);
	rx0_callback();
	
}
void CAN1_RX1_IRQHandler()//CAN_FIFO_1接收中断
{
	//	u8 can_data[8] = {0};
	CAN_Receive(CAN1, CAN_FIFO1, &Rx1_Message);
	rx1_callback();
}
/********************************************************测试程序
#include "LX_OS.h"
GPIO led0(GPIOC,GPIO_Pin_13);
CAN can1(CAN1,&PB8,&PB9);
void fun()
{
uart1.printf_length(uart1.receive_buf,UART_MAX_RECEVE_BUF-DMA_GetCurrDataCounter(DMA1_Channel5));
}
void can_fun()
{
can1.write(Rx0_Message.ExtId,Rx0_Message.Data,Rx0_Message.DLC);
}
void setup()
{
LX_OS_init();
led0.mode(OUTPUT_PP);
//uart1.begin(115200);
//uart1.attach_rx_interrupt(fun);
can1.begin(BSP_CAN_250KBPS);
can1.attach_interrupt_rx0(can_fun);
}
int main()
{
	u16 i = 0;
	u8 data[] = "1234";
	u8 data11;
	u16 data2;
	setup();
	//uart1.printf("Hello World\n");
	can1.write(0x00018b30,data,4);
	while (1)
	{
		led0.toggle();
		delay_ms(500);
	}
}
 ********************************************************/

